package com.lst.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lst.api.constant.RedisKeysConstant;
import com.lst.api.entity.AddressArea;
import com.lst.api.entity.AddressCity;
import com.lst.api.entity.AddressProvince;
import com.lst.api.service.IAddressAreaService;
import com.lst.api.service.IAddressCityService;
import com.lst.api.service.IAddressProvinceService;
import com.lst.api.service.IAddressService;
import com.lst.api.vo.AddressCodeToValueVo;
import com.lst.api.vo.AddressVo;
import com.lst.tools.basics.function.OneParamReturnVoidFunction;
import com.lst.tools.redis.service.impl.RedisService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 地址信息业务层实现
 *
 * @author: Frank
 * @date: 2019/9/29 14:23
 * @version: V1.0
 */
@Service
public class AddressService implements IAddressService {

    @Autowired
    private RedisService redisService;
    @Autowired
    private IAddressProvinceService addressProvinceService;
    @Autowired
    private IAddressCityService addressCityService;
    @Autowired
    private IAddressAreaService addressAreaService;

    @Override
    public List<AddressVo> listAll() {
        String dataJson = redisService.hGet(RedisKeysConstant.ADDRESS, RedisKeysConstant.ADDRESS_LIST_ALL);
        if (StringUtils.isNotBlank(dataJson)) {
            return JSON.parseObject(dataJson, new TypeReference<List<AddressVo>>() {
            });
        }
        List<AddressProvince> addressProvinceList = addressProvinceService.listAll();
        if (CollectionUtils.isEmpty(addressProvinceList)) {
            return Collections.emptyList();
        }
        List<AddressCity> addressCityList = addressCityService.listAll();
        List<AddressArea> addressAreaList = addressAreaService.listAll();

        List<AddressVo> responses = new ArrayList<AddressVo>();
        Map<String, AddressVo> map = new HashMap<String, AddressVo>();
        addressProvinceList.forEach(addressProvince -> {
            AddressVo addressVo = new AddressVo(addressProvince.getCode(), addressProvince.getShortName());
            if (CollectionUtils.isNotEmpty(addressCityList)) {
                List<AddressVo> addressCityVos = new ArrayList<AddressVo>();
                addressCityList.forEach(addressCity -> {
                    if (addressProvince.getCode().equals(addressCity.getProvinceCode())) {
                        AddressVo addressCityVo = new AddressVo(addressCity.getProvinceCode(), addressCity.getCode(), addressCity.getShortName());
                        addressCityVo.setLongitude(addressCity.getLongitude());
                        addressCityVo.setLatitude(addressCity.getLatitude());
                        if (CollectionUtils.isNotEmpty(addressAreaList)) {
                            List<AddressVo> addressAreaVos = new ArrayList<AddressVo>();
                            addressAreaList.forEach(addressArea -> {
                                if (addressCity.getCode().equals(addressArea.getCityCode())) {
                                    AddressVo addressAreaVo = new AddressVo(addressArea.getCityCode(), addressArea.getCode(), addressArea.getShortName());
                                    addressAreaVos.add(addressAreaVo);
                                }
                            });
                            addressCityVo.setSub(addressAreaVos);
                        }
                        addressCityVos.add(addressCityVo);
                        map.put(addressCityVo.getCode(), addressCityVo);
                    }
                });
                addressVo.setSub(addressCityVos);
            }
            responses.add(addressVo);
        });
        if (CollectionUtils.isEmpty(responses)) {
            return Collections.emptyList();
        }
        redisService.hSet(RedisKeysConstant.ADDRESS, RedisKeysConstant.ADDRESS_LIST_ALL, JSON.toJSONString(responses));
        return responses;
    }

    @Override
    public void customValueByCode(AddressCodeToValueVo addressCodeToValueVo) {
        if (addressCodeToValueVo == null) {
            return;
        }
        String provinceCode = addressCodeToValueVo.getProvinceCode();
        if (StringUtils.isNotBlank(provinceCode)) {
            Map<String, String> provinceMap = addressProvinceService.getAllCodeMap();
            addressCodeToValueVo.setProvinceValue(provinceMap.get(provinceCode));
        }
        String cityCode = addressCodeToValueVo.getCityCode();
        if (StringUtils.isNotBlank(cityCode)) {
            Map<String, String> cityMap = addressCityService.getAllCodeMap();
            addressCodeToValueVo.setCityValue(cityMap.get(cityCode));
        }
        String areaCode = addressCodeToValueVo.getAreaCode();
        if (StringUtils.isNotBlank(areaCode)) {
            Map<String, String> areaMap = addressAreaService.getAllCodeMap();
            addressCodeToValueVo.setAreaValue(areaMap.get(areaCode));
        }
    }

    @Override
    public void customValueByCode(String provinceCode, String cityCode, String areaCode, OneParamReturnVoidFunction<AddressCodeToValueVo> fun) {
        AddressCodeToValueVo addressCodeToValueVo = new AddressCodeToValueVo();
        addressCodeToValueVo.setProvinceCode(provinceCode);
        addressCodeToValueVo.setCityCode(cityCode);
        addressCodeToValueVo.setAreaCode(areaCode);
        this.customValueByCode(addressCodeToValueVo);
        if (fun != null) {
            fun.callback(addressCodeToValueVo);
        }
    }
}
